package main;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ItemsBuyer {

	private List<Item> itemsList = new ArrayList<Item>();
	private static String parameterFile = "C:/Trader/properties/java.txt";
	private static String argentFile = "C:/Trader/properties/po.txt";
	private static String PRIX_ACHAT_MAX = "PRIX_ACHAT_MAX"; // po
	private static String PRIX_VENTE_MAX = "PRIX_VENTE_MAX"; // po
	private static String MARGE_MIN = "MARGE_MIN"; // pa
	private static String POURCENTAGE_MIN = "POURCENTAGE_MIN"; // %
	private static String NOMBRE_ITEM_MAX = "NOMBRE_ITEM_MAX"; // Nombre d'items à acheter au maximum
	
	private int prixAchatMax;
	private int prixVenteMax;
	private int margeMin;
	private int pourcentageMin;
	private int nombreItemMax;
	private int argent;
	
	public static void main(String[] args) throws Exception {
		ItemsBuyer margeBuyer = new ItemsBuyer();
		margeBuyer.genererAchat(margeBuyer.getArgent());
	}
	
	public void initParameter() {
		Map<String, Integer> parameters = new HashMap<String, Integer>();
		try {
			InputStream inputStream = new FileInputStream(parameterFile);
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String ligne;
			while ((ligne = bufferedReader.readLine()) != null) {
				parameters.put(ligne.substring(0, ligne.indexOf("=")), Integer.valueOf(ligne.substring(ligne.indexOf("=") + 1)));
			}
			bufferedReader.close();
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		setPrixAchatMax(parameters.get(PRIX_ACHAT_MAX));
		setPrixVenteMax(parameters.get(PRIX_VENTE_MAX));
		setMargeMin(parameters.get(MARGE_MIN));
		setPourcentageMin(parameters.get(POURCENTAGE_MIN));
		setNombreItemMax(parameters.get(NOMBRE_ITEM_MAX));
		
		Integer argent = 0;
		try {
			InputStream inputStream = new FileInputStream(argentFile);
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String ligne;
			while ((ligne = bufferedReader.readLine()) != null) {
				argent = Integer.valueOf(ligne);
			}
			bufferedReader.close();
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		setArgent(argent);
	}
	
	public ItemsBuyer(){
		initParameter();
	}

	public void genererAchat(int po) throws Exception{
		GregorianCalendar greg = new GregorianCalendar();
		StringBuilder sb = new StringBuilder();
		List<Item> itemsListForRequest = new ArrayList<Item>();
		for (Item item : Item.values()){
			itemsListForRequest.add(item);
		}
		recupereValeursWs(itemsListForRequest);
		for (Item item : itemsListForRequest){
			initItem(item);
		}
		Collections.sort(itemsList, new ItemComparator());
		List<Item> itemsToBuy = new ArrayList<Item>();
		int i = 0;
		for (Item item : itemsList){
			i++;
			if (i > getNombreItemMax()){
				break;
			}
			itemsToBuy.add(item);
		}
		System.out.println("Nombre d'items achetables : " + itemsList.size());
		int prixTotal = 0;
		List<Item> itemsToBuyWithQuantite = new ArrayList<Item>();
		while (prixTotal < 10000 * po){
			boolean boucleInutile = true;
			for (Item item : itemsToBuy){
				prixTotal += item.getBuy();
				if (prixTotal < 10000 * po){
					boucleInutile = false;
					item.setQuantite(item.getQuantite() + 1);
					if (itemsToBuyWithQuantite.contains(item)){
						itemsToBuyWithQuantite.set(itemsToBuyWithQuantite.indexOf(item), item);
					} else {
						itemsToBuyWithQuantite.add(item);
					}
				} else {
					prixTotal -= item.getBuy();
				}
			}
			if (boucleInutile){
				break;
			}
		}
		System.out.println("Nombre d'items à acheter : " + itemsToBuyWithQuantite.size());
		for (Item item : itemsToBuyWithQuantite){
			sb.append(item.exportToBotV2());
		}
		System.out.println("Prix total achat : " + prixTotal);
		System.out.println(sb.toString());
		TxtWriter writer = new TxtWriter("C:/Trader/" + getDate(greg) + ".txt");
		writer.write(sb.toString());
	}

	public void initItem(Item item) {
		if (item.getBuy() != 0 && item.getSell() != 0){
			BigDecimal marge = new BigDecimal(item.getSell() * 0.85 - item.getBuy());
			marge = marge.setScale(0, BigDecimal.ROUND_HALF_EVEN);
			item.setMarge(Integer.valueOf(marge.toString()));
			BigDecimal pourcentage = marge.multiply(BigDecimal.valueOf(100)).divide(new BigDecimal(item.getBuy()), 2, BigDecimal.ROUND_HALF_EVEN);
			item.setPourcentage(pourcentage.multiply(BigDecimal.valueOf(100)).intValue());
			if (marge.compareTo(BigDecimal.ZERO) == 1){
				item.setIndiceGlobal(pourcentage.intValue());
			} else {
				item.setIndiceGlobal(0);
			}
			if (item.getBuy() <= getPrixAchatMax() * 10000 && item.getSell() <= getPrixVenteMax() * 10000 && item.getMarge() >= getMargeMin() * 100 && item.getPourcentage() >= getPourcentageMin() * 100){
				itemsList.add(item);
			}
		}
	}
	
	public void recupereValeursWs(List<Item> items) throws Exception {
		List<List<Item>> itemsListOfList = new ArrayList<List<Item>>();
		for (int i=0; i<items.size()/50+1; i++){
			int lastIndex = (i+1)*50;
			if (items.size() < (i+1)*50){
				lastIndex = items.size();
			}
			itemsListOfList.add(items.subList(i*50, lastIndex));
		}
		for (List<Item> subItemsList : itemsListOfList){
			StringBuilder idListe = new StringBuilder();
			for (Item item : subItemsList){
				idListe.append(item.getId() + ",");
			}
			idListe.deleteCharAt(idListe.lastIndexOf(","));
			URL request1 = new URL("http://api.gw2tp.com/1/items?ids=" + idListe +
					"&fields=buy,sell");
			HttpURLConnection httpConnexion1 = (HttpURLConnection) request1.openConnection();
			httpConnexion1.addRequestProperty("User-Agent", "Mozilla/4.76");
			BufferedReader in = new BufferedReader(new InputStreamReader(httpConnexion1.getInputStream()));
			String inputLine;
			StringBuilder sb = new StringBuilder();
			while ((inputLine = in.readLine()) != null){
				sb.append(inputLine);
			}
			in.close();
			for (Item item : subItemsList){
				String currentItem = sb.substring(sb.indexOf("[" + item.getId() + ",") + 1, sb.indexOf("]", sb.indexOf("[" + item.getId() + ",")));
				if (!(item.getId() + "").equals((String) currentItem.split(",")[0])){
					throw new Exception("Echec de la récupération des datas");
				}
				item.setBuy(Integer.valueOf(currentItem.split(",")[1]));
				item.setSell(Integer.valueOf(currentItem.split(",")[2]));
			}
		}
	}
	
	private String getDate(GregorianCalendar greg){
		StringBuilder hour = new StringBuilder();
		if (greg.get(GregorianCalendar.MONTH) + 1 < 10){
			hour.append("0");
		}
		hour.append(greg.get(GregorianCalendar.MONTH) + 1);
		if (greg.get(GregorianCalendar.DAY_OF_MONTH) < 10){
			hour.append("0");
		}
		hour.append(greg.get(GregorianCalendar.DAY_OF_MONTH));
		if (greg.get(GregorianCalendar.HOUR_OF_DAY) < 10){
			hour.append("0");
		}
		hour.append(greg.get(GregorianCalendar.HOUR_OF_DAY));
		if (greg.get(GregorianCalendar.MINUTE) < 10){
			hour.append("0");
		}
		hour.append(greg.get(GregorianCalendar.MINUTE));
		if (greg.get(GregorianCalendar.SECOND) < 10){
			hour.append("0");
		}
		hour.append(greg.get(GregorianCalendar.SECOND));
		return hour.toString();
	}

	public List<Item> getItemsList() {
		return itemsList;
	}

	public void setItemsList(List<Item> itemsList) {
		this.itemsList = itemsList;
	}
	
	public int getPrixAchatMax() {
    	return prixAchatMax;
    }

	public void setPrixAchatMax(int prixAchatMax) {
    	this.prixAchatMax = prixAchatMax;
    }

	public int getPrixVenteMax() {
    	return prixVenteMax;
    }

	public void setPrixVenteMax(int prixVenteMax) {
    	this.prixVenteMax = prixVenteMax;
    }

	public int getMargeMin() {
    	return margeMin;
    }

	public void setMargeMin(int margeMin) {
    	this.margeMin = margeMin;
    }

	public int getPourcentageMin() {
    	return pourcentageMin;
    }

	public void setPourcentageMin(int pourcentageMin) {
    	this.pourcentageMin = pourcentageMin;
    }

	public int getNombreItemMax() {
    	return nombreItemMax;
    }

	public void setNombreItemMax(int nombreItemMax) {
    	this.nombreItemMax = nombreItemMax;
    }

	public int getArgent() {
    	return argent;
    }

	public void setArgent(int argent) {
    	this.argent = argent;
    }

	
}
